﻿using System;
using System.Xml;
using Storm.TextEditor.Editor.CodeCompletion;

namespace Moonlite.Services.CodeCompletion
{
    public class GalaxyNativeObjectsReader
    {
        private const string Path = "Moonlite.Services.CodeCompletion.Resources.Xml.GalaxyNativeObjects.xml";

        public static CompletionDataCollection Types = new CompletionDataCollection();
        public static CompletionDataCollection Natives = new CompletionDataCollection();
        public static CompletionDataCollection Read()
        {
            XmlDocument document = new XmlDocument();
            document.Load(typeof(GalaxyNativeObjectsReader).Assembly.GetManifestResourceStream(Path));
            CompletionDataCollection data = new CompletionDataCollection();
            foreach (XmlNode node in document.ChildNodes)
            {
                if (node.Name.ToLower() == "galaxy")
                {
                    foreach (XmlNode childNode in node.ChildNodes)
                    {
                        string loweredName = childNode.Name.ToLower();
                        if (loweredName != "natives" && loweredName != "types")
                        {
                            continue;
                        }

                        CompletionDataCollection collection = null;
                        int imageIndex = -1;
                        switch (loweredName)
                        {
                            case "natives":
                                collection = Natives;
                                break;
                            case "types":
                                collection = Types;
                                imageIndex = AndromedaImageIndexes.ImageIndexStruct;
                                break;
                            default:
                                break;
                        }

                        string description = "";
                        string keywords = childNode.InnerText;
                        Array.ForEach(keywords.Split(new string[] { Environment.NewLine }, StringSplitOptions.None), keyword =>
                        {
                            keyword = keyword.Trim();
                            if (keyword != "")
                            {
                                IGalaxyObject galaxyObject;
                                string[] dataKeywords = keyword.Split(' ');
                                if (dataKeywords[0] == "var")
                                {
                                    galaxyObject = new GalaxyObjectVariable();
                                    galaxyObject.ObjectType = GalaxyObjectType.Native;
                                    GalaxyObjectVariable variable = galaxyObject as GalaxyObjectVariable;
                                    variable.Name = dataKeywords[2];
                                    variable.Type = dataKeywords[1];
                                    variable.Value = dataKeywords.Length > 3 ? dataKeywords[4] : "";
                                    imageIndex = AndromedaImageIndexes.ImageIndexVariable;
                                    description = variable.Type + " " + variable.Name + (variable.Value != "" ? " = " + variable.Value : "");
                                    keyword = variable.Name;
                                }
                                else if (dataKeywords[0] == "function" || dataKeywords[0] == "native")
                                {
                                    galaxyObject = new GalaxyObjectFunction();
                                    galaxyObject.ObjectType = GalaxyObjectType.Native;
                                    string[] functionKeywords = new string[3];
                                    functionKeywords[0] = dataKeywords[0];
                                    string secondEntry = "";
                                    int entryIndex = 0;
                                    Array.ForEach(dataKeywords, dataEntry =>
                                    {
                                        if (entryIndex >= 2 && entryIndex <= dataKeywords.Length)
                                        {
                                            secondEntry += String.Format("{0} ", dataEntry);
                                        }

                                        entryIndex++;
                                    });

                                    functionKeywords[1] = dataKeywords[1];
                                    functionKeywords[2] = secondEntry;
                                    GalaxyObjectFunction function = galaxyObject as GalaxyObjectFunction;
                                    int paranthesisIndex = functionKeywords[2].IndexOf("(");
                                    int endParanthesisIndex = functionKeywords[2].IndexOf(")");
                                    if (paranthesisIndex > -1 && endParanthesisIndex > -1)
                                    {
                                        string fullArguments = functionKeywords[2].Substring(paranthesisIndex + 1, endParanthesisIndex - paranthesisIndex - 1);
                                        functionKeywords[2] = functionKeywords[2].Remove(paranthesisIndex);
                                        function.Name = functionKeywords[2];
                                        function.Arguments = fullArguments;
                                        function.Type = functionKeywords[1];
                                    }
                                    else
                                    {
                                        throw new Exception("Malformed object data");
                                    }

                                    description = function.Type + " " + function.Name + "(" + function.Arguments + ");";
                                    imageIndex = JassCompletionDataProvider.ImageIndexMethod;
                                    keyword = function.Name;
                                }

                                DefaultCompletionData keywordData = new DefaultCompletionData(imageIndex, keyword, description);
                                data.Add(keywordData);
                                collection.Add(keywordData);
                            }
                        });
                    }
                }
            }

            return data;
        }
    }
}
